

package com.zhanghuan.scheduler.job.service.impl;


import com.zhanghuan.scheduler.job.dao.ScheduleJobDao;
import com.zhanghuan.scheduler.job.entity.ScheduleJobEntity;
import com.zhanghuan.scheduler.job.enums.ScheduleJobStatus;
import com.zhanghuan.scheduler.job.service.ScheduleJobService;
import com.zhanghuan.scheduler.job.utils.ScheduleUtils;
import org.quartz.CronTrigger;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.util.*;

@Service("scheduleJobService")
public class ScheduleJobServiceImpl implements ScheduleJobService {

	@Autowired
	ScheduleJobDao scheduleJobDao;

	@Autowired
    private Scheduler scheduler;
	
	/**
	 * 项目启动时，初始化定时器
	 */
	@PostConstruct
	public void init(){
		List<ScheduleJobEntity> scheduleJobList = scheduleJobDao.findAll();
		for(ScheduleJobEntity scheduleJob : scheduleJobList){
			CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, scheduleJob.getJobId());
            //如果不存在，则创建
            if(cronTrigger == null) {
                ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
            }else {
                ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
            }
		}
	}

	@Override
	public Map<String,Object> findAll(Map<String,Object> map){

		int page = Integer.valueOf((String) map.get("page")) ;
		int limit = Integer.valueOf((String) map.get("limit"));
		String beanName = (String) map.get("beanName");

		if(beanName==null){
			beanName="";
		}
		if( StringUtils.hasLength(beanName.trim()) ){
			int offset = (page-1)*limit;
			List<ScheduleJobEntity> content = scheduleJobDao.findAllByBeanNameLike(beanName,offset,limit);
			long total = scheduleJobDao.countAllByBeanNameLike("%"+beanName+"%");
			map.put("content",content);
			map.put("total",total);
		}else{
			PageRequest pageRequest = PageRequest.of(page-1,limit);
			Page pageObj = scheduleJobDao.findAll(pageRequest);
			List<ScheduleJobEntity> content = pageObj.getContent();
			long total = pageObj.getTotalElements();
			System.out.println(total);
			map.put("content",content);
			map.put("total",total);
		}
		return map;
	}

	@Override
	public ScheduleJobEntity findById(String id) {
		return scheduleJobDao.getOne(id);
	}


	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveJob(ScheduleJobEntity scheduleJob) {
		scheduleJob.setJobId(UUID.randomUUID().toString().replace("-",""));
		scheduleJob.setCreateTime(new Date());
		scheduleJob.setStatus(ScheduleJobStatus.NORMAL.getValue());
        ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
		scheduleJobDao.save(scheduleJob);
    }
	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void update(ScheduleJobEntity scheduleJob) {
        ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
        scheduleJobDao.save(scheduleJob);
    }

	@Override
	@Transactional(rollbackFor = Exception.class)
    public void deleteBatch(String[] jobIds) {
    	for(String jobId : jobIds){
    		ScheduleUtils.deleteScheduleJob(scheduler, jobId);
    	}
    	List<ScheduleJobEntity> list = scheduleJobDao.findAllById(Arrays.asList(jobIds));
    	scheduleJobDao.deleteInBatch(list);

	}

	@Override
    public int updateBatch(String[] jobIds, int status){
		List<ScheduleJobEntity> list = scheduleJobDao.findAllById(Arrays.asList(jobIds));
    	Map<String, Object> map = new HashMap<>(2);
    	int i = 0;
		for (ScheduleJobEntity job:list
			 ) {
			job.setStatus(status);
			scheduleJobDao.save(job);
			i++;
		}
    	return i;
    }
    
	@Override
	@Transactional(rollbackFor = Exception.class)
    public void run(String[] jobIds) {
		ScheduleJobEntity jobEntity;
    	for(String jobId : jobIds){
			jobEntity = scheduleJobDao.findById(jobId).get();
    		ScheduleUtils.run(scheduler, jobEntity );
    	}
    }

	@Override
	@Transactional(rollbackFor = Exception.class)
    public void pause(String[] jobIds) {
        for(String jobId : jobIds){
    		ScheduleUtils.pauseJob(scheduler, jobId);
    	}
        
    	updateBatch(jobIds, ScheduleJobStatus.PAUSE.getValue());
    }

	@Override
	@Transactional(rollbackFor = Exception.class)
    public void resume(String[] jobIds) {
    	for(String jobId : jobIds){
    		ScheduleUtils.resumeJob(scheduler, jobId);
    	}

    	updateBatch(jobIds,ScheduleJobStatus.NORMAL.getValue());
    }
    
}
